﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace SAUlot
{
    public partial class RaportForm : Form
    {
        private const int maxVal = 200;
        private double[] steps = new double[] { 0.5, 0.01, 0.5, 0.5 };

        public delegate void RaportClear();
        public delegate void RaportThis(int chart, double value);
        public delegate void RaportTitle(int chart, String value);
        public delegate void RaportStep(int chart, double value);

        public RaportForm()
        {
            InitializeComponent();

            first.ChartAreas[0].AxisX.Maximum = maxVal;
            first.Series[0].ChartType = SeriesChartType.Area;
            first.Series[0].IsVisibleInLegend = false;

            second.ChartAreas[0].AxisX.Maximum = maxVal;
            second.Series[0].ChartType = SeriesChartType.Area;
            second.Series[0].IsVisibleInLegend = false;

            third.ChartAreas[0].AxisX.Maximum = maxVal;
            third.Series[0].ChartType = SeriesChartType.Area;
            third.Series[0].IsVisibleInLegend = false;

            fourth.ChartAreas[0].AxisX.Maximum = maxVal;
            fourth.Series[0].ChartType = SeriesChartType.Area;
            fourth.Series[0].IsVisibleInLegend = false;
        }

        public void RaportStepHandler(int chart, double value)
        {
            if (value > 0 && steps[chart] != value)
                steps[chart] = value;
        }

        public void RaportClearHandler()
        {
            if (first.InvokeRequired || 
                second.InvokeRequired || 
                third.InvokeRequired || 
                fourth.InvokeRequired)
            {
                RaportClear cb = new RaportClear(RaportClearHandler);
                this.Invoke(cb, new object[] { });
            }
            else
            {
                first.Series[0].Points.Clear();
                second.Series[0].Points.Clear();
                third.Series[0].Points.Clear();
                fourth.Series[0].Points.Clear();
            }
        }
        
        public void RaportTitleHandler(int chart, String value)
        {
            Chart selected = null;
            if (chart == 0)
                selected = first;
            else if (chart == 1)
                selected = second;
            else if (chart == 2)
                selected = third;
            else
                selected = fourth;

            if (selected.InvokeRequired)
            {
                if (selected.Titles[0].Text != value)
                {
                    RaportTitle cb = new RaportTitle(RaportTitleHandler);
                    this.Invoke(cb, new object[] { chart, value });
                }
            }
            else
            {
                selected.Titles[0] = new Title(value);
            }
        }

        public void RaportHandler(int chart, double value)
        {
            Chart selected = null;
            if (chart == 0)
                selected = first;
            else if (chart == 1)
                selected = second;
            else if (chart == 2)
                selected = third;
            else
                selected = fourth;

            if (selected.InvokeRequired)
            {
                RaportThis cb = new RaportThis(RaportHandler);
                this.Invoke(cb, new object[] { chart, value });
            }
            else
            {
                if (selected.Series[0].Points.Count >= maxVal)
                    selected.Series[0].Points.RemoveAt(0);
                selected.Series[0].Points.Add(value);

                double min = Math.Floor(selected.Series[0].Points.Min(x => x.YValues[0] / steps[chart])) * steps[chart];
                if (min >= 0) selected.ChartAreas[0].AxisY.Minimum = 0;
                else selected.ChartAreas[0].AxisY.Minimum = min;

                double max = Math.Ceiling(selected.Series[0].Points.Max(x => x.YValues[0] / steps[chart])) * steps[chart];
                if (max <= 0)
                {
                    if (min >= 0) selected.ChartAreas[0].AxisY.Maximum = steps[chart];
                    else selected.ChartAreas[0].AxisY.Maximum = 0;
                }
                else selected.ChartAreas[0].AxisY.Maximum = max;
            }
        }

        private void RaportForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.ApplicationExitCall)
                return;
            e.Cancel = true;
            Hide();
        }
    }
}
